#ifndef GLOBAL_H
#define GLOBAL_H
#include "flit_queue.h"

typedef enum {IDLE, BUSY} voq_stat_type; 
typedef enum {BERN, POIS} traffic_type;    //Traffic type: bernoulli/poisson
typedef enum {UNIF, HOTS, TRAN} traffic_pattern; //Traffic pattern: uniform/hotspot

//Network parameters
unsigned int NUM_NODES       = 64;
unsigned int NUM_CHN         = 1;  
unsigned int CHN_FLY_TIME    = 16;
double       CHN_PHASE       = CHN_FLY_TIME / NUM_NODES;
unsigned int NUM_FLT_TO_INJ  = 1200;
double       INJ_RATE        = 0.01; 
unsigned int INJ_BUF_DEPTH   = 512; 
unsigned int EJT_BUF_DEPTH   = 100; 
unsigned int SWITCH_PROC_DLY = 0; 
unsigned int FRAME_SZ        = 100; 
traffic_type TRA_TYPE        = BERN;
traffic_pattern TRA_PATTERN  = UNIF;
unsigned int MAX_REQS        = 8;
unsigned int MAX_ACCS        = 2;
unsigned int IDL_LAT         = 8; 
unsigned int STAT_INTV       = 10000;
bool QOS                     = false; //QoS support flag
bool VERBOSE                 = false; 

//Stat counters 
unsigned int num_ejt_flits; 
unsigned int num_inj_flits;
double       total_flit_latency;
double       average_flit_latency; 
double       accepted_throughput;
unsigned int *node_throughputs;
double       dyn_o_power = 0.0;
double       dyn_e_power = 0.0;
double       laser_power = 0.0; 
double       ring_heating_power = 0.0;
unsigned int tot_jitter     = 0; 
unsigned int tot_jitter_var = 0; 
unsigned int num_jitter = 0;
unsigned int *bin_jitter; 

//Global simulator status 
unsigned int SRC_CLK      = 0;
unsigned int DLY_TAP_PT   = 0; 
bool         SIM_END_FLAG = false;
 
//Maps
unsigned int **node_pri_map;
unsigned int **chn_map;

//Queues
flit_queue_t **inj_queues; 
flit_queue_t  *ejt_queues;

//Request and token vector
unsigned int **requests; 
unsigned int *token;
unsigned int *last_requested; 
unsigned int *last_used; 

//Flit delay tap to emulate the flight time latency
flit_t ***flt_dly_tap;

//Completion counter
unsigned int      *comp_counter;
voq_stat_type     **voq_stat; 

//Used for frame-based QOS
int **curr_res;
int **alloc_res;

//Used to "guess" if a node is idle
unsigned int **last_busy_cycle; 
#endif
